/**
 * Project Looking Glass
 *
 * $RCSfile: AxisComponent.java,v $
 *
 * Copyright (c) 2004-2007, Sun Microsystems, Inc., All Rights Reserved
 *
 * Redistributions in source code form must reproduce the above
 * copyright and this condition.
 *
 * The contents of this file are subject to the GNU General Public
 * License, Version 2 (the "License"); you may not use this file
 * except in compliance with the License. A copy of the License is
 * available at http://www.opensource.org/licenses/gpl-license.php.
 *
 * $Revision: 1.5 $
 * $Date: 2007/05/04 23:11:39 $
 * $State: Exp $
 */
package lionel.input;

import javax.swing.event.EventListenerList;
import net.java.games.input.Component;

/**
 * An axis/stick type component of a JInput controller
 *
 * @author Krishna Gadepalli
 */
public class AxisComponent extends JInputComponent {
    boolean isRelative;
    float   deadZone;

    public AxisComponent(JInputDevice device, Component component) {
	super(device, component);

	isRelative = component.isRelative();

	// XXX: A temporary hack since some devices dont seem to report
	//	the dead zone properly
	deadZone = Math.max(component.getDeadZone(), 0.3f);

	if (deadZone > 0.0) {
	    previousValue = currentValue =
		    ((currentValue <  deadZone) &&
		     (currentValue > -deadZone)) ? 0.0f : currentValue;
	}
    }

    public String toString() {
	return component.getName() + "[rel=" + isRelative
			   + ",dz=" + deadZone + ",value=" + currentValue + "]";
    }

    public void update() {
	super.update();

	if (deadZone > 0.0) {
	    currentValue = ((currentValue <  deadZone) &&
			    (currentValue > -deadZone)) ? 0.0f : currentValue;
	}
    }

    /**
     * Figure out the axis events generated after the last poll
     * and send the appropriate events to the registered
     * listeners.
     */
    public void sendEvent(EventListenerList listenerList) {
	if (isRelative && (currentValue == 0.0))
	    return;

	// If we have already sent a '0' event then dont send another.
	if ((currentValue == 0.0) && (previousValue == 0.0))
	    return;

	// Guaranteed to return a non-null array
	Object[] listeners = listenerList.getListenerList();
	AxisEvent e = null;
	// Process the listeners last to first, notifying
	// those that are interested in this event
	for (int i = listeners.length-2; i>=0; i-=2) {
	    if (listeners[i]==AxisEventListener.class) {
		// Lazily create the event:
		if (e == null)
		    e = new AxisEvent(device, this, currentValue);

		((AxisEventListener)listeners[i+1]).axisMoved(e);
	    }          
	}
    }
}
